home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / prog_c / kbstf10.zip / KBSTUFF.C next >
Text File  |  1996-01-31  |  9KB  |  224 lines

  1. #ifndef __TINY__
  2. #error Must be compiled in tiny model
  3. #endif
  4.  
  5. #define NULL 0
  6. #if __STDC__
  7. #define _Cdecl
  8. #else
  9. #define _Cdecl cdecl
  10. #endif
  11.  
  12. void _Cdecl __cli__ (void);
  13. void _Cdecl __sti__ (void);
  14. void _Cdecl __int__(int interruptnum);
  15. extern unsigned _Cdecl _psp;
  16.  
  17. /* *********************************************************************** */
  18. /*   This program stuffs the standard keyboard buffer, which is a  circu-  */
  19. /*  lar buffer of 2-bytes wors                                             */
  20. /*   This 2-bytes words are in general formed by the ASCII translation in  */
  21. /*  the low byte and the scan code in the high byte.  Extended characters  */
  22. /*  could have an ASCII translation of 0 or E0  (for the extended 101/102  */
  23. /*  keys keyboards) or F0 (other extended chars).   You  can inspect keys  */
  24. /*  stored in the keyboard buffer from the standard  INT 9h handler  with  */
  25. /*  the program SEEKBBUF.COM (with Turbo-c source).                        */
  26. /*                                                                         */
  27. /*   The way to use KBSTUFF  is simple for c programmers.                  */
  28. /*   syntax:                                                               */
  29. /*   KBSTUFF [/R] <what to stuff>                                          */
  30. /*     /R          Option. If present must be the first parameter, other-  */
  31. /*                wise is interpreted as two characters to store.          */
  32. /*                 Reset the keyboard's buffer.                            */
  33. /*     <what to stuff> are the characters to store in the buffer.          */
  34. /*                 Blanks and tabs are generally skipped, but you can use  */
  35. /*                a C-type string, as, for example,                        */
  36. /*                  "pippo a:\r"                                           */
  37. /*                  "\r\n\t\aError in C:\\work\r\n"                        */
  38. /*                  "\76\xFDThis are octal and hexadecimal notation\?"     */
  39. /*                 \OOO and \xHHH are accepted as for ANSI C, but if  the  */
  40. /*                value of FFh is exceeded only the low byte is  conside-  */
  41. /*                red and the high is stripped.                            */
  42. /*                 With this "normal" use only ASCII translation are sto-  */
  43. /*                red, without scan code, as the keys would have been ge-  */
  44. /*                nerated with the ALT-key+Keypad numbers combination.     */
  45. /*                 My extensions to C-string allow to store extended keys  */
  46. /*                with a low byte of 0.                                    */
  47. /*                 To store the word 6800h, for example, many methods can  */
  48. /*                be used:                                                 */
  49. /*                  "\0\x68","\ex68" (where the escape sequence \e is  an  */
  50. /*                  extension to the standard C-string syntax), "\0h"  or  */
  51. /*                  "\eh" (where ascii('h')=0x68)                          */
  52. /*                 The x is used as an escape character for the \e escape  */
  53. /*                sequence, so if 7800h(=<ALT 1>) has to be stored can be  */
  54. /*                used:                                                    */
  55. /*                  "\ex78","\0\x78","\0x" or "\exx"                       */
  56. /*                                                                         */
  57. /*                                                                         */
  58. /*   (c) 1996 by Luigi Mancinelli                                          */
  59. /*   manci@alpha.science.unitn.it                                          */
  60. /*                                                                         */
  61. /*   Note: If the program has to be recompiled, the tiny model has  to be  */
  62. /*  used and the resulting .exe has to be converted in .com (with the DOS  */
  63. /*  utility EXE2BIN for example) or the program doesn't work.              */
  64. /*                                                                         */
  65. /* *********************************************************************** */
  66.  
  67. #define MK_FP(seg,ofs)    ((void far *) \
  68.                (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
  69.  
  70.  
  71. #define _toupper(c)    ((c)&0xDF)
  72.  
  73.  
  74. #define putchar(c) (_DL=c,_AH=02,__int__(0x21))
  75.  
  76. #define putbackslash() (_DL='\\',_AH=02,__int__(0x21))
  77.  
  78. void putstring(char *p)
  79. {   unsigned int i=0;
  80.     if (p!=NULL)
  81.        while (p[i]!=0) putchar(p[i++]);
  82. }
  83.  
  84.  
  85. #define FULL 1
  86. #define STRING 2
  87. #define EXTCHAR 4
  88.  
  89.   char Flags=0;
  90.   unsigned int p,Word;
  91.   unsigned char Ch,c;
  92.   unsigned int far *kbdhead  = MK_FP(0x40,0x1A);
  93.   unsigned int far *kbdtail  = MK_FP(0x40,0x1C);
  94.   unsigned int far *kbdbufstart = MK_FP(0x40,0x80);
  95.   unsigned int far *kbdbufend = MK_FP(0x40,0x82);
  96.  
  97.   char OutString[0x100];
  98.   unsigned int l=0;
  99.   char *Mess="Stuffed ...\"";
  100.   char *HexDig="0123456789ABCDEF";
  101.  
  102. /* *************************** */
  103. unsigned char *CmdStr=(unsigned char *) 0x80;
  104. int i=1;
  105.  
  106. void SkipBlanks(void) {
  107.    while ((CmdStr[i]==' ')||(CmdStr[i]==9)) i++;
  108. }
  109.  
  110. /* *************************** */
  111. int GetHexByte(void)
  112. {
  113.    register c;
  114.    unsigned int j=0;
  115.    Ch=0;
  116.    while((j++<3)&&
  117.          ( (((c=CmdStr[i])>='0')&&(c<='9')) ||
  118.            (((c=_toupper(c))>='A')&&(c<='F')) ) )  {
  119.       if(c>='A') c-=('A'-10); else c-='0';
  120.       Ch=(Ch<<4)+c; i++;
  121.    }
  122. }
  123.  
  124.  
  125. main(){
  126. /*
  127. unsigned int DS=((unsigned long)((char far *)(&CmdStr)))>>16;
  128. if(DS==_psp) {
  129. */
  130.     /* is .COM file */
  131.     /* this program must be compiled in tiny model and then */
  132.     /* converted in .COM with exe2bin or it doeSn't work.   */
  133.    {
  134.       putstring(Mess);  /* printf("Stuffed...\""); */
  135.       p=CmdStr[0];
  136.       if(CmdStr[p+1]!=0x0D) CmdStr[p+1]=0x0D;
  137.       SkipBlanks();
  138.       if((CmdStr[i]=='/')&&(_toupper(CmdStr[i+1])=='R')&&
  139.          (((i+2)>p)||(CmdStr[i+2]==' ')||
  140.           (CmdStr[i+2]==9)||(CmdStr[i+2]=='"')) ) {
  141.          __cli__();
  142.          *kbdtail=*kbdhead;
  143.          __sti__();
  144.          i+=2; SkipBlanks();
  145.       }
  146.       while (((Ch=CmdStr[i++])!=0x0D)&&((Flags & FULL)==0)) {
  147.          if((Ch=='"')&& (Flags & STRING)) Flags&=~STRING;
  148.          else {
  149.             if(Ch=='"') {
  150.                register j=i;
  151.                Ch=CmdStr[i++];
  152.                while ((CmdStr[j]!=0x0D)
  153.                       &&((CmdStr[j]!='"')||(CmdStr[j-1]=='\\'))) j++;
  154.                if (CmdStr[j]==0x0D) break; else Flags|=STRING;
  155.             }
  156.             if((Flags & STRING)&&(Ch=='\\')) {
  157.                Ch=CmdStr[i++];
  158.                if((Ch>='0')&&(Ch<='7')) {
  159.                   register j=1; /* register c; */
  160.                   Ch-='0';
  161.                   while((j++<3)&&(((c=CmdStr[i])>='0')&&(c<='7')) )
  162.                      { Ch=(Ch<<3)+(c-'0'); i++; }
  163.                   if(Ch==0) Flags|=EXTCHAR;
  164.                }
  165.                else switch (Ch) {
  166.                /* My extension to standard C-string syntax */
  167.                case 'e':Ch=0;
  168.                         if(CmdStr[i]=='x') {
  169.                            Flags|=EXTCHAR;
  170.                            if(CmdStr[++i]=='x') { Ch='x'; i++; }
  171.                            else GetHexByte();
  172.                         }
  173.                         break;
  174.                /* Normal C-string syntax */
  175.                case 'a':Ch=7; break;
  176.                case 'b':Ch=8; break;
  177.                case 'f':Ch=0x0C; break;
  178.                case 'n':Ch=0x0A; break;
  179.                case 'r':Ch=0x0D; break;
  180.                case 't':Ch=0x09; break;
  181.                case 'v':Ch=0x0B; break;
  182.                case 'X':
  183.                case 'x':GetHexByte();
  184.                         break;
  185.                case '\'':
  186.                case '\?':
  187.                case '"':
  188.                case '\\':break;
  189.                }
  190.             }
  191.             if(Ch==0) Flags|=EXTCHAR;
  192.             else {
  193.                __cli__();
  194.                p=*kbdtail+2;
  195.                if(p==*kbdbufend) p=*kbdbufstart;
  196.                if(p!=*kbdhead) {
  197.                   if(Flags & EXTCHAR) {
  198.                      Word=((unsigned int) Ch)<<8;
  199.                      OutString[l++]='\\'; OutString[l++]='e';
  200.                      if(Ch=='x') OutString[l++]='x';
  201.                   }
  202.                   else Word=Ch & 0xFF;
  203.                   if(Ch=='\\') OutString[l++]='\\';
  204.                   else if((Ch>=32)&&(Ch!=127)&&(Ch!=255)) OutString[l++]=Ch;
  205.                   else {
  206.                      if((Flags & EXTCHAR)==0) OutString[l++]='\\';
  207.                      OutString[l++]='x';
  208.                      OutString[l++]=HexDig[Ch>>4];
  209.                      OutString[l++]=HexDig[Ch& 0xF];
  210.                   }
  211.                   *((int far *) (((long)0x400000)|((long)*kbdtail)) ) = Word;
  212.                   *kbdtail=p;
  213.                } else Flags|=FULL;
  214.                __sti__();
  215.                Flags&=~EXTCHAR;
  216.             }
  217.          }
  218.          if ((Flags & STRING)==0) SkipBlanks();
  219.       }
  220.       OutString[l++]='"'; OutString[l++]='\r'; OutString[l++]='\n';
  221.       putstring(OutString);
  222.    }
  223. /* } */
  224. }